home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / mpzmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  40.0 KB  |  1,827 lines

  1. /* MPZ module */
  2.  
  3. /* This module provides an interface to an alternate Multi-Precision
  4.    library, GNU MP in this case */
  5.  
  6. /* XXX note: everywhere where mpz_size is called,
  7.    sizeof (limb) == sizeof (long)  has been assumed. */
  8.    
  9.  
  10. /* MPZ objects */
  11.  
  12. #include "Python.h"
  13.  
  14. #include <assert.h>
  15. #include <sys/types.h>        /* For size_t */
  16.  
  17. /*
  18. **    These are the cpp-flags used in this file...
  19. **
  20. **
  21. ** MPZ_MDIV_BUG        works around the mpz_m{div,mod,...} routines.
  22. **             This bug has been fixed in a later release of
  23. **             GMP.
  24. ** 
  25. ** MPZ_GET_STR_BUG    mpz_get_str corrupts memory, seems to be fixed
  26. **             in a later release
  27. ** 
  28. ** MPZ_DEBUG        generates a bunch of diagnostic messages
  29. ** 
  30. ** MPZ_SPARE_MALLOC    if set, results in extra code that tries to
  31. **             minimize the creation of extra objects.
  32. ** 
  33. ** MPZ_TEST_DIV        extra diagnostic output on stderr, when division
  34. **             routines are involved
  35. ** 
  36. ** MPZ_LIB_DOES_CHECKING    if set, assumes that mpz library doesn't call
  37. **             alloca with arg < 0 (when casted to a signed
  38. **             integral type).
  39. ** 
  40. ** MPZ_CONVERSIONS_AS_METHODS    if set, presents the conversions as
  41. **             methods. e.g., `mpz(5).long() == 5L'
  42. **             Later, Guido provided an interface to the
  43. **             standard functions. So this flag has no been
  44. **             cleared, and `long(mpz(5)) == 5L'
  45. ** 
  46. ** MP_TEST_ALLOC    If set, you would discover why MPZ_GET_STR_BUG
  47. **            is needed
  48. ** 
  49. ** MAKEDUMMYINT        Must be set if dynamic linking will be used
  50. */
  51.  
  52.  
  53. /*
  54. ** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
  55. ** This has been fixed with gmp release 2.0
  56. */
  57. /*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
  58. /*
  59. ** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
  60. ** allocate it himself
  61. */
  62.  
  63. #include "gmp.h"
  64.  
  65. #if __GNU_MP__ + 0 == 2
  66. #define GMP2
  67. #define BITS_PER_MP_LIMB mp_bits_per_limb
  68. #else
  69. #define MPZ_GET_STR_BUG
  70. #include "gmp-mparam.h"
  71. #endif
  72.  
  73. typedef struct {
  74.     PyObject_HEAD
  75.         MP_INT    mpz;        /* the actual number */
  76. } mpzobject;
  77.  
  78. staticforward PyTypeObject MPZtype;
  79.  
  80. #define is_mpzobject(v)        ((v)->ob_type == &MPZtype)
  81.  
  82. static const char initialiser_name[] = "mpz";
  83.  
  84. /* #define MPZ_DEBUG */
  85.  
  86. static mpzobject *
  87. newmpzobject()
  88. {
  89.     mpzobject *mpzp;
  90.  
  91.  
  92. #ifdef MPZ_DEBUG
  93.     fputs( "mpz_object() called...\n", stderr );
  94. #endif /* def MPZ_DEBUG */
  95.     mpzp = PyObject_New(mpzobject, &MPZtype);
  96.     if (mpzp == NULL)
  97.         return NULL;
  98.  
  99.     mpz_init(&mpzp->mpz);    /* actual initialisation */
  100.     return mpzp;
  101. } /* newmpzobject() */
  102.  
  103. #ifdef MPZ_GET_STR_BUG
  104. #include "longlong.h"
  105. #endif /* def MPZ_GET_STR_BUG */
  106.  
  107. static PyObject *
  108. mpz_format(objp, base, withname)
  109.     PyObject *objp;
  110.     int base;
  111.     unsigned char withname;
  112. {
  113.     mpzobject *mpzp = (mpzobject *)objp;
  114.     PyStringObject *strobjp;
  115.     int i;
  116.     int cmpres;
  117.     int taglong;
  118.     char *cp;
  119.     char prefix[5], *tcp;
  120.  
  121.  
  122.     tcp = &prefix[0];
  123.  
  124.     if (mpzp == NULL || !is_mpzobject(mpzp)) {
  125.         PyErr_BadInternalCall();
  126.         return NULL;
  127.     }
  128.  
  129.     assert(base >= 2 && base <= 36);
  130.  
  131.     if (withname)
  132.         i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
  133.     else
  134.         i = 0;
  135.  
  136.     if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
  137.         base = 10;    /* '0' in every base, right */
  138.     else if (cmpres < 0) {
  139.         *tcp++ = '-';
  140.         i += 1;        /* space to hold '-' */
  141.     }
  142.  
  143. #ifdef MPZ_DEBUG
  144.     fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
  145.         (int)mpz_sizeinbase(&mpzp->mpz, base));
  146. #endif /* def MPZ_DEBUG */
  147. #ifdef MPZ_GET_STR_BUG
  148. #ifdef GMP2
  149.     i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
  150.           * __mp_bases[base].chars_per_bit_exactly) + 1;
  151. #else
  152.     i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
  153.           * __mp_bases[base].chars_per_bit_exactly) + 1;
  154. #endif
  155. #else /* def MPZ_GET_STR_BUG */
  156.     i += (int)mpz_sizeinbase(&mpzp->mpz, base);
  157. #endif /* def MPZ_GET_STR_BUG else */
  158.  
  159.     if (base == 16) {
  160.         *tcp++ = '0';
  161.         *tcp++ = 'x';
  162.         i += 2;        /* space to hold '0x' */
  163.     }
  164.     else if (base == 8) {
  165.         *tcp++ = '0';
  166.         i += 1;        /* space to hold the extra '0' */
  167.     }
  168.     else if (base > 10) {
  169.         *tcp++ = '0' + base / 10;
  170.         *tcp++ = '0' + base % 10;
  171.         *tcp++ = '#';
  172.         i += 3;        /* space to hold e.g. '12#' */
  173.     }
  174.     else if (base < 10) {
  175.         *tcp++ = '0' + base;
  176.         *tcp++ = '#';
  177.         i += 2;        /* space to hold e.g. '6#' */
  178.     }
  179.  
  180.     /*
  181.     ** the following code looks if we need a 'L' attached to the number
  182.     ** it will also attach an 'L' to the value -0x80000000
  183.     */
  184.     taglong = 0;
  185.     if (mpz_size(&mpzp->mpz) > 1
  186.         || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
  187.         taglong = 1;
  188.         i += 1;        /* space to hold 'L' */
  189.     }
  190.  
  191. #ifdef MPZ_DEBUG
  192.     fprintf(stderr, "mpz_format: requesting string size %d\n", i);
  193. #endif /* def MPZ_DEBUG */    
  194.     if ((strobjp =
  195.          (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
  196.         == NULL)
  197.         return NULL;
  198.  
  199.     /* get the beginning of the string memory and start copying things */
  200.     cp = PyString_AS_STRING(strobjp);
  201.     if (withname) {
  202.         strcpy(cp, initialiser_name);
  203.         cp += strlen(initialiser_name);
  204.         *cp++ = '('; /*')'*/
  205.     }
  206.  
  207.     /* copy the already prepared prefix; e.g. sign and base indicator */
  208.     *tcp = '\0';
  209.     strcpy(cp, prefix);
  210.     cp += tcp - prefix;
  211.  
  212.     /* since' we have the sign already, let the lib think it's a positive
  213.        number */
  214.     if (cmpres < 0)
  215.         mpz_neg(&mpzp->mpz,&mpzp->mpz);    /* hack Hack HAck HACk HACK */
  216.     (void)mpz_get_str(cp, base, &mpzp->mpz);
  217.     if (cmpres < 0)
  218.         mpz_neg(&mpzp->mpz,&mpzp->mpz);    /* hack Hack HAck HACk HACK */
  219. #ifdef MPZ_DEBUG
  220.     fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
  221.         base, cp);
  222. #endif /* def MPZ_DEBUG */
  223.     cp += strlen(cp);
  224.  
  225.     if (taglong)
  226.         *cp++ = 'L';
  227.     if (withname)
  228.         *cp++ = /*'('*/ ')';
  229.  
  230.     *cp = '\0';
  231.  
  232. #ifdef MPZ_DEBUG
  233.     fprintf(stderr,
  234.         "mpz_format: cp (str end) 0x%x, begin 0x%x, diff %d, i %d\n",
  235.         cp, PyString_AS_STRING(strobjp),
  236.         cp - PyString_AS_STRING(strobjp), i);
  237. #endif /* def MPZ_DEBUG */    
  238.     assert(cp - PyString_AS_STRING(strobjp) <= i);
  239.  
  240.     if (cp - PyString_AS_STRING(strobjp) != i) {
  241.         strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
  242.     }
  243.  
  244.     return (PyObject *)strobjp;
  245. } /* mpz_format() */
  246.  
  247. /* MPZ methods */
  248.  
  249. static void
  250. mpz_dealloc(mpzp)
  251.     mpzobject *mpzp;
  252. {
  253. #ifdef MPZ_DEBUG
  254.     fputs( "mpz_dealloc() called...\n", stderr );
  255. #endif /* def MPZ_DEBUG */
  256.     mpz_clear(&mpzp->mpz);
  257.     PyObject_Del(mpzp);
  258. } /* mpz_dealloc() */
  259.  
  260.  
  261. /* pointers to frequently used values 0, 1 and -1 */
  262. static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
  263.  
  264. static int
  265. mpz_compare(a, b)
  266.     mpzobject *a, *b;
  267. {
  268.     int cmpres;
  269.  
  270.  
  271.     /* guido sez it's better to return -1, 0 or 1 */
  272.     return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
  273.         : cmpres > 0 ? 1 : -1;
  274. } /* mpz_compare() */
  275.  
  276. static PyObject *
  277. mpz_addition(a, b)
  278.     mpzobject *a;
  279.     mpzobject *b;
  280. {
  281.     mpzobject *z;
  282.  
  283.     
  284. #ifdef MPZ_SPARE_MALLOC
  285.     if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
  286.         Py_INCREF(b);
  287.         return (PyObject *)b;
  288.     }
  289.  
  290.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  291.         Py_INCREF(a);
  292.         return (PyObject *)a;
  293.     }
  294. #endif /* def MPZ_SPARE_MALLOC */
  295.  
  296.     if ((z = newmpzobject()) == NULL)
  297.         return NULL;
  298.     
  299.     mpz_add(&z->mpz, &a->mpz, &b->mpz);
  300.     return (PyObject *)z;
  301. } /* mpz_addition() */
  302.  
  303. static PyObject *
  304. mpz_substract(a, b)
  305.     mpzobject *a;
  306.     mpzobject *b;
  307. {
  308.     mpzobject *z;
  309.  
  310.     
  311. #ifdef MPZ_SPARE_MALLOC
  312.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  313.         Py_INCREF(a);
  314.         return (PyObject *)a;
  315.     }
  316. #endif /* MPZ_SPARE_MALLOC */    
  317.  
  318.     if ((z = newmpzobject()) == NULL)
  319.         return NULL;
  320.  
  321.     mpz_sub(&z->mpz, &a->mpz, &b->mpz);
  322.     return (PyObject *)z;
  323. } /* mpz_substract() */
  324.  
  325. static PyObject *
  326. mpz_multiply(a, b)
  327.     mpzobject *a;
  328.     mpzobject *b;
  329. {
  330. #ifdef MPZ_SPARE_MALLOC
  331.     int cmpres;
  332. #endif /* def MPZ_SPARE_MALLOC */
  333.     mpzobject *z;
  334.  
  335.  
  336. #ifdef MPZ_SPARE_MALLOC
  337.     if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
  338.         Py_INCREF(mpz_value_zero);
  339.         return (PyObject *)mpz_value_zero;
  340.     }
  341.     if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
  342.         Py_INCREF(b);
  343.         return (PyObject *)b;
  344.     }
  345.  
  346.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
  347.         Py_INCREF(mpz_value_zero);
  348.         return (PyObject *)mpz_value_zero;
  349.     }
  350.     if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
  351.         Py_INCREF(a);
  352.         return (PyObject *)a;
  353.     }
  354. #endif /* MPZ_SPARE_MALLOC */
  355.  
  356.     if ((z = newmpzobject()) == NULL)
  357.         return NULL;
  358.  
  359.     mpz_mul( &z->mpz, &a->mpz, &b->mpz );
  360.     return (PyObject *)z;
  361.     
  362. } /* mpz_multiply() */
  363.  
  364. static PyObject *
  365. mpz_divide(a, b)
  366.     mpzobject *a;
  367.     mpzobject *b;
  368. {
  369. #ifdef MPZ_SPARE_MALLOC
  370.     int cmpres;
  371. #endif /* def MPZ_SPARE_MALLOC */
  372.     mpzobject *z;
  373.  
  374.  
  375.     if ((
  376. #ifdef MPZ_SPARE_MALLOC
  377.          cmpres =
  378. #endif /* def MPZ_SPARE_MALLOC */
  379.          mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  380.         PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
  381.         return NULL;
  382.     }
  383. #ifdef MPZ_SPARE_MALLOC
  384.     if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
  385.         Py_INCREF(a);
  386.         return (PyObject *)a;
  387.     }
  388. #endif /* def MPZ_SPARE_MALLOC */
  389.  
  390.     if ((z = newmpzobject()) == NULL)
  391.         return NULL;
  392.  
  393. #ifdef MPZ_TEST_DIV
  394.     fputs("mpz_divide:  div result", stderr);
  395.     mpz_div(&z->mpz, &a->mpz, &b->mpz);
  396.     mpz_out_str(stderr, 10, &z->mpz);
  397.     putc('\n', stderr);
  398. #endif /* def MPZ_TEST_DIV */
  399. #ifdef MPZ_MDIV_BUG
  400.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  401.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
  402.         /*
  403.         ** numerator has other sign than denominator: we have
  404.         ** to look at the remainder for a correction, since mpz_mdiv
  405.         ** also calls mpz_divmod, I can as well do it myself
  406.         */
  407.         MP_INT tmpmpz;
  408.  
  409.  
  410.         mpz_init(&tmpmpz);
  411.         mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
  412.  
  413.         if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
  414.             mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
  415.  
  416.         mpz_clear(&tmpmpz);
  417.     }
  418.     else
  419.         mpz_div(&z->mpz, &a->mpz, &b->mpz);
  420.         /* the ``naive'' implementation does it right for operands
  421.            having the same sign */
  422.  
  423. #else /* def MPZ_MDIV_BUG */
  424.     mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
  425. #endif /* def MPZ_MDIV_BUG else */
  426. #ifdef MPZ_TEST_DIV
  427.     fputs("mpz_divide: mdiv result", stderr);
  428.     mpz_out_str(stderr, 10, &z->mpz);
  429.     putc('\n', stderr);
  430. #endif /* def MPZ_TEST_DIV */
  431.     return (PyObject *)z;
  432.     
  433. } /* mpz_divide() */
  434.  
  435. static PyObject *
  436. mpz_remainder(a, b)
  437.     mpzobject *a;
  438.     mpzobject *b;
  439. {
  440. #ifdef MPZ_SPARE_MALLOC
  441.     int cmpres;
  442. #endif /* def MPZ_SPARE_MALLOC */    
  443.     mpzobject *z;
  444.  
  445.     
  446.     if ((
  447. #ifdef MPZ_SPARE_MALLOC         
  448.          cmpres =
  449. #endif /* def MPZ_SPARE_MALLOC */    
  450.          mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  451.         PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
  452.         return NULL;
  453.     }
  454. #ifdef MPZ_SPARE_MALLOC
  455.     if (cmpres > 0) {
  456.         if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
  457.         {
  458.             Py_INCREF(mpz_value_one);
  459.             return (PyObject *)mpz_value_one;
  460.         }
  461.         if (cmpres < 0) {
  462.             /* b must be 1 now */
  463.             Py_INCREF(mpz_value_zero);
  464.             return (PyObject *)mpz_value_zero;
  465.         }
  466.     }
  467. #endif /* def MPZ_SPARE_MALLOC */    
  468.  
  469.     if ((z = newmpzobject()) == NULL)
  470.         return NULL;
  471.  
  472. #ifdef MPZ_TEST_DIV
  473.     fputs("mpz_remain:  mod result", stderr);
  474.     mpz_mod(&z->mpz, &a->mpz, &b->mpz);
  475.     mpz_out_str(stderr, 10, &z->mpz);
  476.     putc('\n', stderr);
  477. #endif /* def MPZ_TEST_DIV */
  478. #ifdef MPZ_MDIV_BUG
  479.  
  480.     /* the ``naive'' implementation does it right for operands
  481.        having the same sign */
  482.     mpz_mod(&z->mpz, &a->mpz, &b->mpz);
  483.  
  484.     /* assumption: z, a and b all point to different locations */
  485.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  486.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
  487.         && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
  488.         mpz_add(&z->mpz, &z->mpz, &b->mpz);
  489.         /*
  490.         ** numerator has other sign than denominator: we have
  491.         ** to look at the remainder for a correction, since mpz_mdiv
  492.         ** also calls mpz_divmod, I can as well do it myself
  493.         */
  494. #else /* def MPZ_MDIV_BUG */
  495.     mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
  496. #endif /* def MPZ_MDIV_BUG else */
  497. #ifdef MPZ_TEST_DIV
  498.     fputs("mpz_remain: mmod result", stderr);
  499.     mpz_out_str(stderr, 10, &z->mpz);
  500.     putc('\n', stderr);
  501. #endif /* def MPZ_TEST_DIV */
  502.     return (PyObject *)z;
  503.     
  504. } /* mpz_remainder() */
  505.  
  506. static PyObject *
  507. mpz_div_and_mod(a, b)
  508.     mpzobject *a;
  509.     mpzobject *b;
  510. {
  511.     PyObject *z = NULL;
  512.     mpzobject *x = NULL, *y = NULL;
  513.  
  514.  
  515.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  516.         PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
  517.         return NULL;
  518.     }
  519.  
  520.     if ((z = PyTuple_New(2)) == NULL
  521.         || (x = newmpzobject()) == NULL
  522.         || (y = newmpzobject()) == NULL) {
  523.         Py_XDECREF(z);
  524.         Py_XDECREF(x);
  525.         Py_XDECREF(y);
  526.         return NULL;
  527.     }
  528.  
  529. #ifdef MPZ_TEST_DIV
  530.     fputs("mpz_divmod:  dm  result", stderr);
  531.     mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
  532.     mpz_out_str(stderr, 10, &x->mpz);
  533.     putc('\n', stderr);
  534.     mpz_out_str(stderr, 10, &y->mpz);
  535.     putc('\n', stderr);
  536. #endif /* def MPZ_TEST_DIV */
  537. #ifdef MPZ_MDIV_BUG
  538.     mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
  539.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  540.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
  541.         && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
  542.         /*
  543.         ** numerator has other sign than denominator: we have
  544.         ** to look at the remainder for a correction.
  545.         */
  546.         mpz_add(&y->mpz, &y->mpz, &b->mpz);
  547.         mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
  548.     }
  549. #else /* def MPZ_MDIV_BUG */
  550.     mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
  551. #endif /* def MPZ_MDIV_BUG else */
  552. #ifdef MPZ_TEST_DIV
  553.     fputs("mpz_divmod: mdm  result", stderr);
  554.     mpz_out_str(stderr, 10, &x->mpz);
  555.     putc('\n', stderr);
  556.     mpz_out_str(stderr, 10, &y->mpz);
  557.     putc('\n', stderr);
  558. #endif /* def MPZ_TEST_DIV */
  559.  
  560.     (void)PyTuple_SetItem(z, 0, (PyObject *)x);
  561.     (void)PyTuple_SetItem(z, 1, (PyObject *)y);
  562.     
  563.     return z;
  564. } /* mpz_div_and_mod() */
  565.  
  566. static PyObject *
  567. mpz_power(a, b, m)
  568.     mpzobject *a;
  569.     mpzobject *b;
  570.         mpzobject *m;
  571. {
  572.     mpzobject *z;
  573.     int cmpres;
  574.  
  575.      if ((PyObject *)m != Py_None) {
  576.         mpzobject *z2;
  577.         Py_INCREF(Py_None);
  578.         z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
  579.         Py_DECREF(Py_None);
  580.         if (z==NULL) return((PyObject *)z);
  581.         z2=(mpzobject *)mpz_remainder(z, m);
  582.         Py_DECREF(z);
  583.         return((PyObject *)z2);
  584.     }        
  585.  
  586.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  587.         /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
  588.  
  589.         Py_INCREF(mpz_value_one);
  590.         return (PyObject *)mpz_value_one;
  591.     }
  592.         
  593.     if (cmpres < 0) {
  594.         PyErr_SetString(PyExc_ValueError,
  595.                 "mpz.pow to negative exponent");
  596.         return NULL;
  597.     }
  598.  
  599.     if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
  600.         /* the base is 0 */
  601.  
  602.         Py_INCREF(mpz_value_zero);
  603.         return (PyObject *)mpz_value_zero;
  604.     }
  605.     else if (cmpres > 0
  606.          && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
  607.         /* the base is 1 */
  608.  
  609.         Py_INCREF(mpz_value_one);
  610.         return (PyObject *)mpz_value_one;
  611.     }
  612.     else if (cmpres < 0
  613.          && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
  614.  
  615.         MP_INT tmpmpz;
  616.         /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
  617.         /* XXX this code needs to be optimized: what's better?
  618.            mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
  619.            for *un*obvious reasons */
  620.  
  621.         /* is the exponent even? */
  622.         mpz_init(&tmpmpz);
  623.  
  624.         /* look to the remainder after a division by (1 << 1) */
  625.         mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
  626.  
  627.         if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
  628.             mpz_clear(&tmpmpz);
  629.             Py_INCREF(mpz_value_one);
  630.             return (PyObject *)mpz_value_one;
  631.         }
  632.         mpz_clear(&tmpmpz);
  633.         Py_INCREF(mpz_value_mone);
  634.         return (PyObject *)mpz_value_mone;
  635.     }
  636.  
  637. #ifdef MPZ_LIB_DOES_CHECKING
  638.     /* check if it's doable: sizeof(exp) > sizeof(long) &&
  639.        abs(base) > 1 ?? --> No Way */
  640.     if (mpz_size(&b->mpz) > 1)
  641.         return (PyObject *)PyErr_NoMemory();
  642. #else /* def MPZ_LIB_DOES_CHECKING */
  643.     /* wet finger method */
  644.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
  645.         PyErr_SetString(PyExc_ValueError,
  646.                 "mpz.pow outrageous exponent");
  647.         return NULL;
  648.     }
  649. #endif /* def MPZ_LIB_DOES_CHECKING else */
  650.  
  651.     if ((z = newmpzobject()) == NULL)
  652.         return NULL;
  653.     
  654.     mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  655.     
  656.     return (PyObject *)z;
  657. } /* mpz_power() */
  658.  
  659.  
  660. static PyObject *
  661. mpz_negative(v)
  662.     mpzobject *v;
  663. {
  664.     mpzobject *z;
  665.  
  666.     
  667. #ifdef MPZ_SPARE_MALLOC
  668.     if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
  669.         /* -0 == 0 */
  670.         Py_INCREF(v);
  671.         return (PyObject *)v;
  672.     }
  673. #endif /* def MPZ_SPARE_MALLOC */
  674.  
  675.     if ((z = newmpzobject()) == NULL)
  676.         return NULL;
  677.  
  678.     mpz_neg(&z->mpz, &v->mpz);
  679.     return (PyObject *)z;
  680. } /* mpz_negative() */
  681.  
  682.  
  683. static PyObject *
  684. mpz_positive(v)
  685.     mpzobject *v;
  686. {
  687.     Py_INCREF(v);
  688.     return (PyObject *)v;
  689. } /* mpz_positive() */
  690.  
  691.  
  692. static PyObject *
  693. mpz_absolute(v)
  694.     mpzobject *v;
  695. {
  696.     mpzobject *z;
  697.  
  698.     
  699.     if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
  700.         Py_INCREF(v);
  701.         return (PyObject *)v;
  702.     }
  703.  
  704.     if ((z = newmpzobject()) == NULL)
  705.         return NULL;
  706.  
  707.     mpz_neg(&z->mpz, &v->mpz);
  708.     return (PyObject *)z;
  709. } /* mpz_absolute() */
  710.  
  711. static int
  712. mpz_nonzero(v)
  713.     mpzobject *v;
  714. {
  715.     return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
  716. } /* mpz_nonzero() */
  717.         
  718. static PyObject *
  719. py_mpz_invert(v)
  720.     mpzobject *v;
  721. {
  722.     mpzobject *z;
  723.  
  724.  
  725.     /* I think mpz_com does exactly what needed */
  726.     if ((z = newmpzobject()) == NULL)
  727.         return NULL;
  728.  
  729.     mpz_com(&z->mpz, &v->mpz);
  730.     return (PyObject *)z;
  731. } /* py_mpz_invert() */
  732.  
  733. static PyObject *
  734. mpz_lshift(a, b)
  735.     mpzobject *a;
  736.     mpzobject *b;
  737. {
  738.     int cmpres;
  739.     mpzobject *z;
  740.  
  741.  
  742.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  743.         /* a << 0 == a */
  744.         Py_INCREF(a);
  745.         return (PyObject *)a;
  746.     }
  747.  
  748.     if (cmpres < 0) {
  749.         PyErr_SetString(PyExc_ValueError,
  750.                 "mpz.<< negative shift count");
  751.         return NULL;
  752.     }
  753.  
  754. #ifdef MPZ_LIB_DOES_CHECKING
  755.     if (mpz_size(&b->mpz) > 1)
  756.         return (PyObject *)PyErr_NoMemory();
  757. #else /* def MPZ_LIB_DOES_CHECKING */
  758.     /* wet finger method */
  759.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
  760.         PyErr_SetString(PyExc_ValueError,
  761.                 "mpz.<< outrageous shift count");
  762.         return NULL;
  763.     }
  764. #endif /* def MPZ_LIB_DOES_CHECKING else */
  765.  
  766.     if ((z = newmpzobject()) == NULL)
  767.         return NULL;
  768.  
  769.     mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  770.     return (PyObject *)z;
  771. } /* mpz_lshift() */
  772.  
  773. static PyObject *
  774. mpz_rshift(a, b)
  775.     mpzobject *a;
  776.     mpzobject *b;
  777. {
  778.     int cmpres;
  779.     mpzobject *z;
  780.  
  781.  
  782.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  783.         /* a >> 0 == a */
  784.         Py_INCREF(a);
  785.         return (PyObject *)a;
  786.     }
  787.  
  788.     if (cmpres < 0) {
  789.         PyErr_SetString(PyExc_ValueError,
  790.                 "mpz.>> negative shift count");
  791.         return NULL;
  792.     }
  793.  
  794.     if (mpz_size(&b->mpz) > 1)
  795.         return (PyObject *)PyErr_NoMemory();
  796.  
  797.     if ((z = newmpzobject()) == NULL)
  798.         return NULL;
  799.  
  800.     mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  801.     return (PyObject *)z;
  802. } /* mpz_rshift() */
  803.  
  804. static PyObject *
  805. mpz_andfunc(a, b)
  806.     mpzobject *a;
  807.     mpzobject *b;
  808. {
  809.     mpzobject *z;
  810.  
  811.  
  812.     if ((z = newmpzobject()) == NULL)
  813.         return NULL;
  814.  
  815.     mpz_and(&z->mpz, &a->mpz, &b->mpz);
  816.     return (PyObject *)z;
  817. } /* mpz_andfunc() */
  818.  
  819. /* hack Hack HAck HACk HACK, XXX this code is dead slow */
  820. void
  821. mpz_xor(res, op1, op2)
  822.     MP_INT *res;
  823.     const MP_INT *op1;
  824.     const MP_INT *op2;
  825. {
  826.     MP_INT tmpmpz;
  827.     
  828.     mpz_init(&tmpmpz);
  829.  
  830.     mpz_and(res, op1, op2);
  831.     mpz_com(&tmpmpz, res);
  832.     mpz_ior(res, op1, op2);
  833.     mpz_and(res, res, &tmpmpz);
  834.  
  835.     mpz_clear(&tmpmpz);
  836. } /* mpz_xor() HACK */
  837.  
  838. static PyObject *
  839. mpz_xorfunc(a, b)
  840.     mpzobject *a;
  841.     mpzobject *b;
  842. {
  843.     mpzobject *z;
  844.  
  845.  
  846.     if ((z = newmpzobject()) == NULL)
  847.         return NULL;
  848.  
  849.     mpz_xor(&z->mpz, &a->mpz, &b->mpz);
  850.     return (PyObject *)z;
  851. } /* mpz_xorfunc() */
  852.  
  853. static PyObject *
  854. mpz_orfunc(a, b)
  855.     mpzobject *a;
  856.     mpzobject *b;
  857. {
  858.     mpzobject *z;
  859.  
  860.  
  861.     if ((z = newmpzobject()) == NULL)
  862.         return NULL;
  863.  
  864.     mpz_ior(&z->mpz, &a->mpz, &b->mpz);
  865.     return (PyObject *)z;
  866. } /* mpz_orfunc() */
  867.  
  868. /* MPZ initialisation */
  869.  
  870. #include "longintrepr.h"
  871.  
  872. static PyObject *
  873. MPZ_mpz(self, args)
  874.     PyObject *self;
  875.     PyObject *args;
  876. {
  877.     mpzobject *mpzp;
  878.     PyObject *objp;
  879.  
  880.  
  881. #ifdef MPZ_DEBUG
  882.     fputs("MPZ_mpz() called...\n", stderr);
  883. #endif /* def MPZ_DEBUG */
  884.  
  885.     if (!PyArg_Parse(args, "O", &objp))
  886.         return NULL;
  887.  
  888.     /* at least we know it's some object */
  889.     /* note DON't Py_DECREF args NEITHER objp */
  890.  
  891.     if (PyInt_Check(objp)) {
  892.         long lval;
  893.  
  894.         if (!PyArg_Parse(objp, "l", &lval))
  895.             return NULL;
  896.         
  897.         if (lval == (long)0) {
  898.             Py_INCREF(mpz_value_zero);
  899.             mpzp = mpz_value_zero;
  900.         }
  901.         else if (lval == (long)1) {
  902.             Py_INCREF(mpz_value_one);
  903.             mpzp = mpz_value_one;
  904.         }            
  905.         else if ((mpzp = newmpzobject()) == NULL)
  906.             return NULL;
  907.         else mpz_set_si(&mpzp->mpz, lval);
  908.     }
  909.     else if (PyLong_Check(objp)) {
  910.         MP_INT mplongdigit;
  911.         int i;
  912.         unsigned char isnegative;
  913.         
  914.  
  915.         if ((mpzp = newmpzobject()) == NULL)
  916.             return NULL;
  917.  
  918.         mpz_set_si(&mpzp->mpz, 0L);
  919.         mpz_init(&mplongdigit);
  920.         
  921.         /* how we're gonna handle this? */
  922.         if ((isnegative =
  923.              ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
  924.             i = -i;
  925.  
  926.         while (i--) {
  927.             mpz_set_ui(&mplongdigit,
  928.                    (unsigned long)
  929.                    ((PyLongObject *)objp)->ob_digit[i]);
  930.             mpz_mul_2exp(&mplongdigit,&mplongdigit,
  931.                      (unsigned long int)i * SHIFT);
  932.             mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
  933.         }
  934.  
  935.         if (isnegative)
  936.             mpz_neg(&mpzp->mpz, &mpzp->mpz);
  937.  
  938.         /* get rid of allocation for tmp variable */
  939.         mpz_clear(&mplongdigit);
  940.     }
  941.     else if (PyString_Check(objp)) {
  942.         unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
  943.         int len = PyString_GET_SIZE(objp);
  944.         MP_INT mplongdigit;
  945.  
  946.         if ((mpzp = newmpzobject()) == NULL)
  947.             return NULL;
  948.  
  949.         mpz_set_si(&mpzp->mpz, 0L);
  950.         mpz_init(&mplongdigit);
  951.         
  952.         /* let's do it the same way as with the long conversion:
  953.            without thinking how it can be faster (-: :-) */
  954.  
  955.         cp += len;
  956.         while (len--) {
  957.             mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
  958.             mpz_mul_2exp(&mplongdigit,&mplongdigit,
  959.                      (unsigned long int)len * 8);
  960.             mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
  961.         }
  962.  
  963.         /* get rid of allocation for tmp variable */
  964.         mpz_clear(&mplongdigit);
  965.     }
  966.     else if (is_mpzobject(objp)) {
  967.         Py_INCREF(objp);
  968.         mpzp = (mpzobject *)objp;
  969.     }
  970.     else {
  971.         PyErr_SetString(PyExc_TypeError,
  972. "mpz.mpz() expects integer, long, string or mpz object argument");
  973.         return NULL;
  974.     }
  975.  
  976.  
  977. #ifdef MPZ_DEBUG
  978.     fputs("MPZ_mpz: created mpz=", stderr);
  979.     mpz_out_str(stderr, 10, &mpzp->mpz);
  980.     putc('\n', stderr);
  981. #endif /* def MPZ_DEBUG */
  982.     return (PyObject *)mpzp;
  983. } /* MPZ_mpz() */
  984.  
  985. static mpzobject *
  986. mpz_mpzcoerce(z)
  987.     PyObject *z;
  988. {
  989.     /* shortcut: 9 out of 10 times the type is already ok */
  990.     if (is_mpzobject(z)) {
  991.         Py_INCREF(z);
  992.         return (mpzobject *)z;    /* coercion succeeded */
  993.     }
  994.  
  995.     /* what types do we accept?: intobjects and longobjects */
  996.     if (PyInt_Check(z) || PyLong_Check(z))
  997.         return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
  998.  
  999.     PyErr_SetString(PyExc_TypeError,
  1000.             "number coercion (to mpzobject) failed");
  1001.     return NULL;
  1002. } /* mpz_mpzcoerce() */
  1003.     
  1004. /* Forward */
  1005. static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
  1006.                    const MP_INT *den, const MP_INT *mod));
  1007.  
  1008. static PyObject *
  1009. MPZ_powm(self, args)
  1010.     PyObject *self;
  1011.     PyObject *args;
  1012. {
  1013.     PyObject *base, *exp, *mod;
  1014.     mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
  1015.     mpzobject *z;
  1016.     int tstres;
  1017.  
  1018.     
  1019.     if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
  1020.         return NULL;
  1021.  
  1022.     if ((mpzbase = mpz_mpzcoerce(base)) == NULL
  1023.         || (mpzexp = mpz_mpzcoerce(exp)) == NULL
  1024.         || (mpzmod = mpz_mpzcoerce(mod)) == NULL
  1025.         || (z = newmpzobject()) == NULL) {
  1026.         Py_XDECREF(mpzbase);
  1027.         Py_XDECREF(mpzexp);
  1028.         Py_XDECREF(mpzmod);
  1029.         return NULL;
  1030.     }
  1031.  
  1032.     if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
  1033.         Py_INCREF(mpz_value_one);
  1034.         return (PyObject *)mpz_value_one;
  1035.     }
  1036.  
  1037.     if (tstres < 0) {
  1038.         MP_INT absexp;
  1039.         /* negative exp */
  1040.  
  1041.         mpz_init_set(&absexp, &mpzexp->mpz);
  1042.         mpz_abs(&absexp, &absexp);
  1043.         mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
  1044.  
  1045.         mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
  1046.         
  1047.         mpz_clear(&absexp);
  1048.     }
  1049.     else {
  1050.         mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
  1051.     }
  1052.         
  1053.     Py_DECREF(mpzbase);
  1054.     Py_DECREF(mpzexp);
  1055.     Py_DECREF(mpzmod);
  1056.  
  1057.     return (PyObject *)z;
  1058. } /* MPZ_powm() */
  1059.  
  1060.  
  1061. static PyObject *
  1062. MPZ_gcd(self, args)
  1063.     PyObject *self;
  1064.     PyObject *args;
  1065. {
  1066.     PyObject *op1, *op2;
  1067.     mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
  1068.     mpzobject *z;
  1069.  
  1070.     
  1071.     if (!PyArg_Parse(args, "(OO)", &op1, &op2))
  1072.         return NULL;
  1073.  
  1074.     if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
  1075.         || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
  1076.         || (z = newmpzobject()) == NULL) {
  1077.         Py_XDECREF(mpzop1);
  1078.         Py_XDECREF(mpzop2);
  1079.         return NULL;
  1080.     }
  1081.  
  1082.     /* ok, we have three mpzobjects, and an initialised result holder */
  1083.     mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
  1084.  
  1085.     Py_DECREF(mpzop1);
  1086.     Py_DECREF(mpzop2);
  1087.  
  1088.     return (PyObject *)z;
  1089. } /* MPZ_gcd() */
  1090.  
  1091.  
  1092. static PyObject *
  1093. MPZ_gcdext(self, args)
  1094.     PyObject *self;
  1095.     PyObject *args;
  1096. {
  1097.     PyObject *op1, *op2, *z = NULL;
  1098.     mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
  1099.     mpzobject *g = NULL, *s = NULL, *t = NULL;
  1100.  
  1101.     
  1102.     if (!PyArg_Parse(args, "(OO)", &op1, &op2))
  1103.         return NULL;
  1104.  
  1105.     if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
  1106.         || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
  1107.         || (z = PyTuple_New(3)) == NULL
  1108.         || (g = newmpzobject()) == NULL
  1109.         || (s = newmpzobject()) == NULL
  1110.         || (t = newmpzobject()) == NULL) {
  1111.         Py_XDECREF(mpzop1);
  1112.         Py_XDECREF(mpzop2);
  1113.         Py_XDECREF(z);
  1114.         Py_XDECREF(g);
  1115.         Py_XDECREF(s);
  1116.         /*Py_XDECREF(t);*/
  1117.         return NULL;
  1118.     }
  1119.  
  1120.     mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
  1121.  
  1122.     Py_DECREF(mpzop1);
  1123.     Py_DECREF(mpzop2);
  1124.  
  1125.     (void)PyTuple_SetItem(z, 0, (PyObject *)g);
  1126.     (void)PyTuple_SetItem(z, 1, (PyObject *)s);
  1127.     (void)PyTuple_SetItem(z, 2, (PyObject *)t);
  1128.  
  1129.     return (PyObject *)z;
  1130. } /* MPZ_gcdext() */
  1131.  
  1132.  
  1133. static PyObject *
  1134. MPZ_sqrt(self, args)
  1135.     PyObject *self;
  1136.     PyObject *args;
  1137. {
  1138.     PyObject *op;
  1139.     mpzobject *mpzop = NULL;
  1140.     mpzobject *z;
  1141.  
  1142.     
  1143.     if (!PyArg_Parse(args, "O", &op))
  1144.         return NULL;
  1145.  
  1146.     if ((mpzop = mpz_mpzcoerce(op)) == NULL
  1147.         || (z = newmpzobject()) == NULL) {
  1148.         Py_XDECREF(mpzop);
  1149.         return NULL;
  1150.     }
  1151.  
  1152.     mpz_sqrt(&z->mpz, &mpzop->mpz);
  1153.  
  1154.     Py_DECREF(mpzop);
  1155.  
  1156.     return (PyObject *)z;
  1157. } /* MPZ_sqrt() */
  1158.  
  1159.  
  1160. static PyObject *
  1161. MPZ_sqrtrem(self, args)
  1162.     PyObject *self;
  1163.     PyObject *args;
  1164. {
  1165.     PyObject *op, *z = NULL;
  1166.     mpzobject *mpzop = NULL;
  1167.     mpzobject *root = NULL, *rem = NULL;
  1168.  
  1169.     
  1170.     if (!PyArg_Parse(args, "O", &op))
  1171.         return NULL;
  1172.  
  1173.     if ((mpzop = mpz_mpzcoerce(op)) == NULL
  1174.         || (z = PyTuple_New(2)) == NULL
  1175.         || (root = newmpzobject()) == NULL
  1176.         || (rem = newmpzobject()) == NULL) {
  1177.         Py_XDECREF(mpzop);
  1178.         Py_XDECREF(z);
  1179.         Py_XDECREF(root);
  1180.         /*Py_XDECREF(rem);*/
  1181.         return NULL;
  1182.     }
  1183.  
  1184.     mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
  1185.  
  1186.     Py_DECREF(mpzop);
  1187.  
  1188.     (void)PyTuple_SetItem(z, 0, (PyObject *)root);
  1189.     (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
  1190.  
  1191.     return (PyObject *)z;
  1192. } /* MPZ_sqrtrem() */
  1193.  
  1194.  
  1195. static void
  1196. #if __STDC__
  1197. mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
  1198. #else
  1199. mpz_divm(res, num, den, mod)
  1200.     MP_INT *res;
  1201.     const MP_INT *num;
  1202.     const MP_INT *den;
  1203.     const MP_INT *mod;
  1204. #endif
  1205. {
  1206.     MP_INT s0, s1, q, r, x, d0, d1;
  1207.  
  1208.     mpz_init_set(&s0, num);
  1209.     mpz_init_set_ui(&s1, 0);
  1210.     mpz_init(&q);
  1211.     mpz_init(&r);
  1212.     mpz_init(&x);
  1213.     mpz_init_set(&d0, den);
  1214.     mpz_init_set(&d1, mod);
  1215.  
  1216. #ifdef GMP2
  1217.     while (d1._mp_size != 0) {
  1218. #else
  1219.     while (d1.size != 0) {
  1220. #endif
  1221.         mpz_divmod(&q, &r, &d0, &d1);
  1222.         mpz_set(&d0, &d1);
  1223.         mpz_set(&d1, &r);
  1224.  
  1225.         mpz_mul(&x, &s1, &q);
  1226.         mpz_sub(&x, &s0, &x);
  1227.         mpz_set(&s0, &s1);
  1228.         mpz_set(&s1, &x);
  1229.     }
  1230.  
  1231. #ifdef GMP2
  1232.     if (d0._mp_size != 1 || d0._mp_d[0] != 1)
  1233.         res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
  1234. #else
  1235.     if (d0.size != 1 || d0.d[0] != 1)
  1236.         res->size = 0;    /* trouble: the gcd != 1; set s to zero */
  1237. #endif
  1238.     else {
  1239. #ifdef MPZ_MDIV_BUG
  1240.         /* watch out here! first check the signs, and then perform
  1241.            the mpz_mod() since mod could point to res */
  1242.         if ((s0.size < 0) != (mod->size < 0)) {
  1243.             mpz_mod(res, &s0, mod);
  1244.  
  1245.             if (res->size)
  1246.                 mpz_add(res, res, mod);
  1247.         }
  1248.         else
  1249.             mpz_mod(res, &s0, mod);
  1250.         
  1251. #else /* def MPZ_MDIV_BUG */
  1252.         mpz_mmod(res, &s0, mod);
  1253. #endif /* def MPZ_MDIV_BUG else */
  1254.     }
  1255.  
  1256.     mpz_clear(&s0);
  1257.     mpz_clear(&s1);
  1258.     mpz_clear(&q);
  1259.     mpz_clear(&r);
  1260.     mpz_clear(&x);
  1261.     mpz_clear(&d0);
  1262.     mpz_clear(&d1);
  1263. } /* mpz_divm() */
  1264.  
  1265.  
  1266. static PyObject *
  1267. MPZ_divm(self, args)
  1268.     PyObject *self;
  1269.     PyObject *args;
  1270. {
  1271.     PyObject *num, *den, *mod;
  1272.     mpzobject *mpznum, *mpzden, *mpzmod = NULL;
  1273.     mpzobject *z = NULL;
  1274.  
  1275.     
  1276.     if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
  1277.         return NULL;
  1278.  
  1279.     if ((mpznum = mpz_mpzcoerce(num)) == NULL
  1280.         || (mpzden = mpz_mpzcoerce(den)) == NULL
  1281.         || (mpzmod = mpz_mpzcoerce(mod)) == NULL
  1282.         || (z = newmpzobject()) == NULL ) {
  1283.         Py_XDECREF(mpznum);
  1284.         Py_XDECREF(mpzden);
  1285.         Py_XDECREF(mpzmod);
  1286.         return NULL;
  1287.     }
  1288.     
  1289.     mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
  1290.  
  1291.     Py_DECREF(mpznum);
  1292.     Py_DECREF(mpzden);
  1293.     Py_DECREF(mpzmod);
  1294.  
  1295.     if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
  1296.         Py_DECREF(z);
  1297.         PyErr_SetString(PyExc_ValueError,
  1298.                 "gcd(den, mod) != 1 or num == 0");
  1299.         return NULL;
  1300.     }
  1301.  
  1302.     return (PyObject *)z;
  1303. } /* MPZ_divm() */
  1304.  
  1305.  
  1306. /* MPZ methods-as-attributes */
  1307. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1308. static PyObject *
  1309. mpz_int(self, args)
  1310.     mpzobject *self;
  1311.     PyObject *args;
  1312. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1313. static PyObject *
  1314. mpz_int(self)
  1315.     mpzobject *self;
  1316. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1317. {
  1318.     long sli;
  1319.  
  1320.  
  1321. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1322.     if (!PyArg_NoArgs(args))
  1323.         return NULL;
  1324. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1325.  
  1326.     if (mpz_size(&self->mpz) > 1
  1327.         || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
  1328.         PyErr_SetString(PyExc_ValueError,
  1329.                 "mpz.int() arg too long to convert");
  1330.         return NULL;
  1331.     }
  1332.  
  1333.     if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
  1334.         sli = -sli;
  1335.  
  1336.     return PyInt_FromLong(sli);
  1337. } /* mpz_int() */
  1338.     
  1339. static PyObject *
  1340. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1341. mpz_long(self, args)
  1342.     mpzobject *self;
  1343.     PyObject *args;
  1344. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1345. mpz_long(self)
  1346.     mpzobject *self;
  1347. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1348. {
  1349.     int i, isnegative;
  1350.     unsigned long int uli;
  1351.     PyLongObject *longobjp;
  1352.     int ldcount;
  1353.     int bitpointer, newbitpointer;
  1354.     MP_INT mpzscratch;
  1355.  
  1356.  
  1357. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1358.     if (!PyArg_NoArgs(args))
  1359.         return NULL;
  1360. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1361.  
  1362.     /* determine length of python-long to be allocated */
  1363.     if ((longobjp = _PyLong_New(i = (int)
  1364.                 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
  1365.                   + SHIFT - 1) /
  1366.                  SHIFT))) == NULL)
  1367.         return NULL;
  1368.  
  1369.     /* determine sign, and copy self to scratch var */
  1370.     mpz_init_set(&mpzscratch, &self->mpz);
  1371.     if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
  1372.         mpz_neg(&mpzscratch, &mpzscratch);
  1373.  
  1374.     /* let those bits come, let those bits go,
  1375.        e.g. dismantle mpzscratch, build PyLongObject */
  1376.  
  1377.     bitpointer = 0;        /* the number of valid bits in stock */
  1378.     newbitpointer = 0;
  1379.     ldcount = 0;        /* the python-long limb counter */
  1380.     uli = (unsigned long int)0;
  1381.     while (i--) {
  1382.         longobjp->ob_digit[ldcount] = uli & MASK;
  1383.  
  1384.         /* check if we've had enough bits for this digit */
  1385.         if (bitpointer < SHIFT) {
  1386.             uli = mpz_get_ui(&mpzscratch);
  1387.             longobjp->ob_digit[ldcount] |=
  1388.                 (uli << bitpointer) & MASK;
  1389.             uli >>= SHIFT-bitpointer;
  1390.             bitpointer += BITS_PER_MP_LIMB;
  1391.             mpz_div_2exp(&mpzscratch, &mpzscratch,
  1392.                      BITS_PER_MP_LIMB);
  1393.         }
  1394.         else
  1395.             uli >>= SHIFT;
  1396.         bitpointer -= SHIFT;
  1397.         ldcount++;
  1398.     }
  1399.  
  1400.     assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
  1401.     mpz_clear(&mpzscratch);
  1402.     assert(ldcount <= longobjp->ob_size);
  1403.  
  1404.     /* long_normalize() is file-static */
  1405.     /* longobjp = long_normalize(longobjp); */
  1406.     while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
  1407.         ldcount--;
  1408.     longobjp->ob_size = ldcount;
  1409.     
  1410.  
  1411.     if (isnegative)
  1412.         longobjp->ob_size = -longobjp->ob_size;
  1413.  
  1414.     return (PyObject *)longobjp;
  1415.     
  1416. } /* mpz_long() */
  1417.  
  1418.  
  1419. /* I would have avoided pow() anyways, so ... */
  1420. static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
  1421.     
  1422. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1423. static PyObject *
  1424. mpz_float(self, args)
  1425.     mpzobject *self;
  1426.     PyObject *args;
  1427. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1428. static PyObject *
  1429. mpz_float(self)
  1430.     mpzobject *self;
  1431. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1432. {
  1433.     int i, isnegative;
  1434.     double x;
  1435.     double mulstate;
  1436.     MP_INT mpzscratch;
  1437.  
  1438.  
  1439. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1440.     if (!PyArg_NoArgs(args))
  1441.         return NULL;
  1442. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1443.  
  1444.     i = (int)mpz_size(&self->mpz);
  1445.     
  1446.     /* determine sign, and copy abs(self) to scratch var */
  1447.     if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
  1448.     {
  1449.         mpz_init(&mpzscratch);
  1450.         mpz_neg(&mpzscratch, &self->mpz);
  1451.     }
  1452.     else
  1453.         mpz_init_set(&mpzscratch, &self->mpz);
  1454.  
  1455.     /* let those bits come, let those bits go,
  1456.        e.g. dismantle mpzscratch, build PyFloatObject */
  1457.  
  1458.     /* Can this overflow?  Dunno, protect against that possibility. */
  1459.     PyFPE_START_PROTECT("mpz_float", return 0)
  1460.     x = 0.0;
  1461.     mulstate = 1.0;
  1462.     while (i--) {
  1463.         x += mulstate * mpz_get_ui(&mpzscratch);
  1464.         mulstate *= multiplier;
  1465.         mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
  1466.     }
  1467.     PyFPE_END_PROTECT(mulstate)
  1468.  
  1469.     assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
  1470.     mpz_clear(&mpzscratch);
  1471.  
  1472.     if (isnegative)
  1473.         x = -x;
  1474.  
  1475.     return PyFloat_FromDouble(x);
  1476.     
  1477. } /* mpz_float() */
  1478.  
  1479. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1480. static PyObject *
  1481. mpz_hex(self, args)
  1482.     mpzobject *self;
  1483.     PyObject *args;
  1484. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1485. static PyObject *
  1486. mpz_hex(self)
  1487.     mpzobject *self;
  1488. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1489. {
  1490. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1491.     if (!PyArg_NoArgs(args))
  1492.         return NULL;
  1493. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1494.     
  1495.     return mpz_format(self, 16, (unsigned char)1);
  1496. } /* mpz_hex() */
  1497.     
  1498. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1499. static PyObject *
  1500. mpz_oct(self, args)
  1501.     mpzobject *self;
  1502.     PyObject *args;
  1503. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1504. static PyObject *
  1505. mpz_oct(self)
  1506.     mpzobject *self;
  1507. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1508. {
  1509. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1510.     if (!PyArg_NoArgs(args))
  1511.         return NULL;
  1512. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1513.     
  1514.     return mpz_format(self, 8, (unsigned char)1);
  1515. } /* mpz_oct() */
  1516.     
  1517. static PyObject *
  1518. mpz_binary(self, args)
  1519.     mpzobject *self;
  1520.     PyObject *args;
  1521. {
  1522.     int size;
  1523.     PyStringObject *strobjp;
  1524.     char *cp;
  1525.     MP_INT mp;
  1526.     unsigned long ldigit;
  1527.     
  1528.     if (!PyArg_NoArgs(args))
  1529.         return NULL;
  1530.  
  1531.     if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
  1532.         PyErr_SetString(PyExc_ValueError,
  1533.                 "mpz.binary() arg must be >= 0");
  1534.         return NULL;
  1535.     }
  1536.  
  1537.     mpz_init_set(&mp, &self->mpz);
  1538.     size = (int)mpz_size(&mp);
  1539.  
  1540.     if ((strobjp = (PyStringObject *)
  1541.          PyString_FromStringAndSize(
  1542.              (char *)0, size * sizeof (unsigned long int))) == NULL)
  1543.         return NULL;
  1544.  
  1545.     /* get the beginning of the string memory and start copying things */
  1546.     cp = PyString_AS_STRING(strobjp);
  1547.  
  1548.     /* this has been programmed using a (fairly) decent lib-i/f it could
  1549.        be must faster if we looked into the GMP lib */
  1550.     while (size--) {
  1551.         ldigit = mpz_get_ui(&mp);
  1552.         mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
  1553.         *cp++ = (unsigned char)(ldigit & 0xFF);
  1554.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1555.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1556.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1557.     }
  1558.  
  1559.     while (strobjp->ob_size && !*--cp)
  1560.         strobjp->ob_size--;
  1561.  
  1562.     return (PyObject *)strobjp;
  1563. } /* mpz_binary() */
  1564.     
  1565.  
  1566. static PyMethodDef mpz_methods[] = {
  1567. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1568.     {"int",            mpz_int},
  1569.     {"long",        mpz_long},
  1570.     {"float",        mpz_float},
  1571.     {"hex",            mpz_hex},
  1572.     {"oct",            mpz_oct},
  1573. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1574.     {"binary",        (PyCFunction)mpz_binary},
  1575.     {NULL,            NULL}        /* sentinel */
  1576. };
  1577.  
  1578. static PyObject *
  1579. mpz_getattr(self, name)
  1580.     mpzobject *self;
  1581.     char *name;
  1582. {
  1583.     return Py_FindMethod(mpz_methods, (PyObject *)self, name);
  1584. } /* mpz_getattr() */
  1585.  
  1586.  
  1587. static int
  1588. mpz_coerce(pv, pw)
  1589.     PyObject **pv;
  1590.     PyObject **pw;
  1591. {
  1592.     PyObject *z;
  1593.  
  1594. #ifdef MPZ_DEBUG
  1595.     fputs("mpz_coerce() called...\n", stderr);
  1596. #endif /* def MPZ_DEBUG */
  1597.  
  1598.     assert(is_mpzobject(*pv));
  1599.  
  1600.     /* always convert other arg to mpz value, except for floats */
  1601.     if (!PyFloat_Check(*pw)) {
  1602.         if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
  1603.             return -1;    /* -1: an error always has been set */
  1604.         
  1605.         Py_INCREF(*pv);
  1606.         *pw = z;
  1607.     }
  1608.     else {
  1609.         if ((z = mpz_float(*pv, NULL)) == NULL)
  1610.             return -1;
  1611.  
  1612.         Py_INCREF(*pw);
  1613.         *pv = z;
  1614.     }
  1615.     return 0;        /* coercion succeeded */
  1616.  
  1617. } /* mpz_coerce() */
  1618.  
  1619.  
  1620. static PyObject *
  1621. mpz_repr(v)
  1622.     PyObject *v;
  1623. {
  1624.     return mpz_format(v, 10, (unsigned char)1);
  1625. } /* mpz_repr() */
  1626.  
  1627.  
  1628.  
  1629. #define UF (unaryfunc)
  1630. #define BF (binaryfunc)
  1631. #define TF (ternaryfunc)
  1632. #define IF (inquiry)
  1633. #define CF (coercion)
  1634.  
  1635. static PyNumberMethods mpz_as_number = {
  1636.     BF mpz_addition,    /*nb_add*/
  1637.     BF mpz_substract,    /*nb_subtract*/
  1638.     BF mpz_multiply,    /*nb_multiply*/
  1639.     BF mpz_divide,        /*nb_divide*/
  1640.     BF mpz_remainder,    /*nb_remainder*/
  1641.     BF mpz_div_and_mod,    /*nb_divmod*/
  1642.     TF mpz_power,        /*nb_power*/
  1643.     UF mpz_negative,    /*nb_negative*/
  1644.     UF mpz_positive,    /*tp_positive*/
  1645.     UF mpz_absolute,    /*tp_absolute*/
  1646.     IF mpz_nonzero,        /*tp_nonzero*/
  1647.     UF py_mpz_invert,    /*nb_invert*/
  1648.     BF mpz_lshift,        /*nb_lshift*/
  1649.     BF mpz_rshift,        /*nb_rshift*/
  1650.     BF mpz_andfunc,        /*nb_and*/
  1651.     BF mpz_xorfunc,        /*nb_xor*/
  1652.     BF mpz_orfunc,        /*nb_or*/
  1653.     CF mpz_coerce,        /*nb_coerce*/
  1654. #ifndef MPZ_CONVERSIONS_AS_METHODS
  1655.     UF mpz_int,        /*nb_int*/
  1656.     UF mpz_long,        /*nb_long*/
  1657.     UF mpz_float,        /*nb_float*/
  1658.     UF mpz_oct,        /*nb_oct*/
  1659.     UF mpz_hex,        /*nb_hex*/
  1660. #endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
  1661. };
  1662.  
  1663. static PyTypeObject MPZtype = {
  1664.     PyObject_HEAD_INIT(&PyType_Type)
  1665.     0,            /*ob_size*/
  1666.     "mpz",            /*tp_name*/
  1667.     sizeof(mpzobject),    /*tp_size*/
  1668.     0,            /*tp_itemsize*/
  1669.     /* methods */
  1670.     (destructor)mpz_dealloc, /*tp_dealloc*/
  1671.     0,            /*tp_print*/
  1672.     (getattrfunc)mpz_getattr, /*tp_getattr*/
  1673.     0,            /*tp_setattr*/
  1674.     (cmpfunc)mpz_compare,    /*tp_compare*/
  1675.     (reprfunc)mpz_repr,    /*tp_repr*/
  1676.         &mpz_as_number,     /*tp_as_number*/
  1677. };
  1678.  
  1679. /* List of functions exported by this module */
  1680.  
  1681. static PyMethodDef mpz_functions[] = {
  1682. #if 0
  1683.     {initialiser_name,    MPZ_mpz},
  1684. #else /* 0 */
  1685.     /* until guido ``fixes'' struct PyMethodDef */
  1686.     {(char *)initialiser_name,    MPZ_mpz},
  1687. #endif /* 0 else */    
  1688.     {"powm",        MPZ_powm},
  1689.     {"gcd",            MPZ_gcd},
  1690.     {"gcdext",        MPZ_gcdext},
  1691.     {"sqrt",        MPZ_sqrt},
  1692.     {"sqrtrem",        MPZ_sqrtrem},
  1693.     {"divm",        MPZ_divm},
  1694.     {NULL,            NULL}         /* Sentinel */
  1695. };
  1696.  
  1697.  
  1698. /* #define MP_TEST_ALLOC */
  1699.  
  1700. #ifdef MP_TEST_ALLOC
  1701. #define MP_TEST_SIZE        4
  1702. static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
  1703. static mp_test_error( location )
  1704.     int *location;
  1705. {
  1706.     /* assumptions: *alloc returns address dividable by 4,
  1707.     mpz_* routines allocate in chunks dividable by four */
  1708.     fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
  1709.     Py_FatalError("MP_TEST_ERROR");
  1710. } /* static mp_test_error() */
  1711. #define MP_EXTRA_ALLOC(size)    ((size) + MP_TEST_SIZE)
  1712. #define MP_SET_TEST(basep,size)    (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
  1713. #define MP_DO_TEST(basep,size)    if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
  1714.                     ; \
  1715.                 else \
  1716.                     mp_test_error((int *)((char *)(basep) + size))
  1717. #else /* def MP_TEST_ALLOC */
  1718. #define MP_EXTRA_ALLOC(size)    (size)
  1719. #define MP_SET_TEST(basep,size)
  1720. #define MP_DO_TEST(basep,size)
  1721. #endif /* def MP_TEST_ALLOC else */
  1722.  
  1723. void *mp_allocate( alloc_size )
  1724.     size_t    alloc_size;
  1725. {
  1726.     void *res;
  1727.  
  1728. #ifdef MPZ_DEBUG
  1729.     fprintf(stderr, "mp_allocate  :                             size %ld\n",
  1730.         alloc_size);
  1731. #endif /* def MPZ_DEBUG */    
  1732.  
  1733.     if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
  1734.         Py_FatalError("mp_allocate failure");
  1735.  
  1736. #ifdef MPZ_DEBUG
  1737.     fprintf(stderr, "mp_allocate  :     address 0x%08x\n", res);
  1738. #endif /* def MPZ_DEBUG */    
  1739.  
  1740.     MP_SET_TEST(res,alloc_size);
  1741.     
  1742.     return res;
  1743. } /* mp_allocate() */
  1744.  
  1745.  
  1746. void *mp_reallocate( ptr, old_size, new_size )
  1747.     void *ptr;
  1748.     size_t old_size;
  1749.     size_t new_size;
  1750. {
  1751.     void *res;
  1752.  
  1753. #ifdef MPZ_DEBUG
  1754.     fprintf(stderr, "mp_reallocate: old address 0x%08x, old size %ld\n",
  1755.         ptr, old_size);
  1756. #endif /* def MPZ_DEBUG */    
  1757.  
  1758.     MP_DO_TEST(ptr, old_size);
  1759.     
  1760.     if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
  1761.         Py_FatalError("mp_reallocate failure");
  1762.  
  1763. #ifdef MPZ_DEBUG
  1764.     fprintf(stderr, "mp_reallocate: new address 0x%08x, new size %ld\n",
  1765.         res, new_size);
  1766. #endif /* def MPZ_DEBUG */    
  1767.  
  1768.     MP_SET_TEST(res, new_size);
  1769.  
  1770.     return res;
  1771. } /* mp_reallocate() */
  1772.  
  1773.  
  1774. void mp_free( ptr, size )
  1775.     void *ptr;
  1776.     size_t size;
  1777. {
  1778.  
  1779. #ifdef MPZ_DEBUG
  1780.     fprintf(stderr, "mp_free      : old address 0x%08x, old size %ld\n",
  1781.         ptr, size);
  1782. #endif /* def MPZ_DEBUG */    
  1783.  
  1784.     MP_DO_TEST(ptr, size);
  1785.     free(ptr);
  1786. } /* mp_free() */
  1787.  
  1788.  
  1789.  
  1790. /* Initialize this module. */
  1791.  
  1792. DL_EXPORT(void)
  1793. initmpz()
  1794. {
  1795.     PyObject *module;
  1796.     PyObject *dict;
  1797.  
  1798. #ifdef MPZ_DEBUG
  1799.     fputs( "initmpz() called...\n", stderr );
  1800. #endif /* def MPZ_DEBUG */
  1801.  
  1802.     mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
  1803.     module = Py_InitModule("mpz", mpz_functions);
  1804.  
  1805.     /* create some frequently used constants */
  1806.     if ((mpz_value_zero = newmpzobject()) == NULL)
  1807.         Py_FatalError("initmpz: can't initialize mpz constants");
  1808.     mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
  1809.  
  1810.     if ((mpz_value_one = newmpzobject()) == NULL)
  1811.         Py_FatalError("initmpz: can't initialize mpz constants");
  1812.     mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
  1813.  
  1814.     if ((mpz_value_mone = newmpzobject()) == NULL)
  1815.         Py_FatalError("initmpz: can't initialize mpz constants");
  1816.     mpz_set_si(&mpz_value_mone->mpz, (long)-1);
  1817.  
  1818.     dict = PyModule_GetDict(module);
  1819.     if (dict != NULL) {
  1820.         PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
  1821.     }
  1822.  
  1823. } /* initmpz() */
  1824. #ifdef MAKEDUMMYINT
  1825. int _mpz_dummy_int;    /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
  1826. #endif /* def MAKEDUMMYINT */
  1827.